using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Advent.aiDevices;

namespace Advent.Controls
{
    public partial class MeterPulseGen : UserControl
    {

        MeteringPulseGenerator Gen;

        public MeterPulseGen()
        {
            InitializeComponent();
            this.EnabledChanged += new EventHandler(MeterPulseGenCtrl_EnabledChanged);


            txt_Interval.Validating += new CancelEventHandler(txt_Interval_Validating);
            txt_Interval.KeyUp += new KeyEventHandler(txt_Interval_KeyUp);

            level_Pulse.SignalLevelChanged += new EventHandler(UpdateSignalSpecification);
            freq_Pulse.FrequencyChanged += new EventHandler(UpdateSignalSpecification);
            txt_Duration.Validating += new CancelEventHandler(txt_Duration_Validating);
            txt_Duration.KeyUp += new KeyEventHandler(txt_Duration_KeyUp);
        }
        /// <summary>
        /// This specifies the metering pulse generator which will be manipulated by this control
        /// </summary>
        public void SetGenerator(MeteringPulseGenerator Gen)
        {
            this.Gen = Gen;
            RefreshControls();
        }


        #region Signal Parameters

        void txt_Duration_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode != Keys.Return) return;
            UpdateSignalSpecification(null,EventArgs.Empty);
        }
  

        void txt_Duration_Validating(object sender, CancelEventArgs e)
        {
            UpdateSignalSpecification(null, EventArgs.Empty);
        }

        void UpdateSignalSpecification(object sender, EventArgs e)
        {
            try
            {
                Gen.Signal = ParseSignal();
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
        }
      #endregion




        #region Interval

        void txt_Interval_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode != Keys.Return) return;
            UpdateInterval();
        }

        void txt_Interval_Validating(object sender, CancelEventArgs e)
        {
            UpdateInterval();
        }

        private void UpdateInterval()
        {
            try
            {
                if (Gen == null) return;
                Gen.Interval = ParseInterval();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private TimeInterval ParseInterval()
        {
            double interval = 0;

            if ((!double.TryParse(txt_Interval.Text, out interval)) || (interval <=0))  
                    throw new Exception("Invalid interval value");

            return TimeInterval.InSeconds(interval);
        }

        #endregion

        void MeterPulseGenCtrl_EnabledChanged(object sender, EventArgs e)
        {
            timer_Update.Enabled = this.Enabled;
        }




        
        /// <summary>
        /// This refreshed the contents of the user controls with the values within the 
        /// generator
        /// </summary>
        private void RefreshControls()
        {

            MeteringPulse Pulse = Gen.Signal;
            level_Pulse.Level = Pulse.Level;
            freq_Pulse.Freq = Pulse.Frequency;
            txt_Duration.Text = Pulse.Duration.ValueInMilliseconds.ToString();
            txt_Interval.Text = Gen.Interval.Value.ToString();
        }

        private void timer_Update_Tick(object sender, EventArgs e)
        {
            try
            {
                if (Gen == null) return;

                string Status = "Metering Pulse Generator ";

                if (Gen.IsActive)
                {
                    if (Gen.IsGeneratingIndefinitely)
                    {
                        Status += " (active indefinitely)";

                    }else {

                        Status += " (active, " + Gen.Count.ToString() + " remaining)";
                    }
                }

                gb_Generator.Text = Status;
            }
            catch { }
        }

        /// <summary>
        /// This returns a MeteringPulse object based on the contents of the user controls
        /// </summary>
        private MeteringPulse ParseSignal()
        {
            double Duration;

            if ((!double.TryParse(txt_Duration.Text, out Duration)) || (Duration <= 0))
                throw new Exception("Invalid duration specified");

            return new MeteringPulse(level_Pulse.Level, freq_Pulse.Freq, TimeInterval.InMilliseconds(Duration));
        }



        private void btn_GenerateFinite_Click(object sender, EventArgs e)
        {
            try
            {

                if (rb_Infinite.Checked)
                {
                    // Generate metering pulses indefinitely
                    Gen.Generate(ParseSignal(), ParseInterval());
                }
                else
                {
                    int Count;

                    if ((!int.TryParse(txt_Count.Text,out Count)) || (Count <=0))
                        throw new Exception("Invalid count value specified");

                    Gen.Generate(ParseSignal(), ParseInterval(), Count);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                RefreshControls();
            }
        }

        private void btn_Stop_Click(object sender, EventArgs e)
        {
            try
            {
                Gen.StopGenerator();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                RefreshControls();
            }
        }

        private void btn_Reset_Click(object sender, EventArgs e)
        {
            try
            {
                Gen.ResetToDefaults();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                RefreshControls();
            }
        }


    }
}
